﻿using IA.Shopping.UI.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace IA.Shopping.UI
{
    public class Shopping
    {
        private static Bloco[,] _matriz = null;
        public static Int32 QTDAgentes { get; set; }
        public static List<Agente> Agentes { get; set; }
        public static List<Agente> AgentesBuscaCompleta { get; set; }
        public static List<Loja> Lojas { get; set; }
        public static Bloco[,] Matriz { get { return Shopping._matriz; } set { Shopping._matriz = value; } }
        public static ListaDeCompras ItensAComprar { get; set; }
        public static HashSet<RegistroParaCompra> RegistroLoja { get; set; }

        public static bool prontoParaCompra()
        {
            if (AgenteAtivosCount() == RegistroLoja.Count ||
                QuantidadeLojasNaoVisitas() <= RegistroLoja.Count)
            {
                return true;
            }
            return false;
        }

        private static int AgenteAtivosCount()
        {
            int count = 0;

            foreach (Agente agente in Agentes)
            {
                if (agente._ativo)
                    count++;
            }
            return count;
        }


        /* Coloca os valores dos produtos na loja atual na lista de compras
         * caso eles sejam melhores dos que ja existem.
         */
        public static bool avisarSobreLojaEncontrada(Agente agente, Loja loja)
        {
            bool registrado = false;

            foreach (int produtoID in ItensAComprar.produtosRetantes())
            {
                Produto produtoEmLoja = loja.buscarProduto(produtoID);
                float valorProdutoLista = ItensAComprar.Produto(produtoID).Valor();

                if (produtoEmLoja != null &&
                    (valorProdutoLista == Util.SEM_VALOR ||
                    produtoEmLoja._Valor < valorProdutoLista))
                {
                    ItensAComprar.Produto(produtoID)._Valor = produtoEmLoja._Valor;
                    registrado = true;
                }
            }

            if (registrado)
            {
                RegistroLoja.Add(new RegistroParaCompra(agente, loja));
                return true;
            }
            return false;
        }

        public static void Inicializar()
        {
            Agentes = new List<Agente>();
            Lojas = new List<Loja>();
            RegistroLoja = new HashSet<RegistroParaCompra>();

            _matriz = new Bloco[Util.DIMENSAO_MATRIZ, Util.DIMENSAO_MATRIZ];
            for (int i = 0; i < Util.DIMENSAO_MATRIZ; i++)
            {
                for (int j = 0; j < Util.DIMENSAO_MATRIZ; j++)
                {
                    //adiciona elemento na matriz
                    _matriz[i, j] = new Bloco
                    {
                        Posicao = new Point(i, j),
                        Cor = Cor.BRANCO,
                        Loja = null,
                        AgenteID = null
                    };
                    var pos = _matriz[i, j].Posicao;
                  //  Console.Write(String.Format("{0}{1} ", pos.X, pos.Y));
                }
               // Console.WriteLine(Environment.NewLine);
            }
            ItensAComprar = new ListaDeCompras();

        }

        public static void CriarUI(Grid grdShopping)
        {
            var columnWidth = (Util.MIN_WIDTH / Util.DIMENSAO_MATRIZ) - 1;
            var rowHeight = ((Util.MIN_HEIGHT * 80 / 100) / Util.DIMENSAO_MATRIZ) - 2;

            for (int i = 0; i < Util.DIMENSAO_MATRIZ; i++)
            {
                for (int j = 0; j < Util.DIMENSAO_MATRIZ; j++)
                {
                    grdShopping.ColumnDefinitions.Add(new ColumnDefinition { MinWidth = columnWidth });
                    grdShopping.RowDefinitions.Add(new RowDefinition { MinHeight = rowHeight });

                    Rectangle rect = new Rectangle { Height = rowHeight - 10, Width = columnWidth - 10, Fill = new SolidColorBrush(Colors.White) };
                    Grid.SetColumn(rect, j);
                    Grid.SetRow(rect, i);
                    grdShopping.Children.Add(rect);

                }
            }

            CriarLojas();
            DistribuirLojas(grdShopping);
        }

        private static void CriarLojas()
        {
            Lojas = new List<Loja>();

            for (int l = 0; l < Util.QUANTIDADE_LOJAS; l++)
            {
                Loja loja = new Loja();
                loja.criarProdutosParaLoja(l);
                Lojas.Add(loja);
            }
        }

        private static void DistribuirLojas(Grid grdShopping)
        {
            HashSet<Point> locais = new HashSet<Point>();

            while (locais.Count < Util.QUANTIDADE_LOJAS)
            {
                Point ponto = new Point
                {
                    X = Util.random.Next(0, Util.DIMENSAO_MATRIZ - 1),
                    Y = Util.random.Next(0, Util.DIMENSAO_MATRIZ - 1)
                };

                if ((ponto.X == 0 && ponto.Y == 0) ||
                    (ponto.X == 0 && ponto.Y == Util.DIMENSAO_MATRIZ - 1) ||
                    (ponto.X == Util.DIMENSAO_MATRIZ - 1 && ponto.Y == 0) ||
                    (ponto.X == Util.DIMENSAO_MATRIZ - 1 && ponto.Y == Util.DIMENSAO_MATRIZ - 1))
                {
                    continue;
                }

                locais.Add(ponto);
            }

            for (int i = 0; i < locais.Count; i++)
            {
                var point = locais.ElementAt(i);

                var imagemLoja = ImagemUtil.CriarLoja(Colors.Orange);
                Grid.SetColumn(imagemLoja, (int)point.Y);
                Grid.SetRow(imagemLoja, (int)point.X);
                grdShopping.Children.Add(imagemLoja);

                Bloco bloco = _matriz[(int)point.X, (int)point.Y];
                bloco.Loja = Lojas[i];
            }
        }

        private static int QuantidadeLojasNaoVisitas()
        {
            int count = 0;
            foreach (Loja j in Lojas)
            {
                if (!j._LojaJaVisita)
                    count++;
            }
            return count;
        }

        public static bool FaltaComprarAlgumItem()
        {
            foreach (bool comprado in ItensAComprar._Comprado)
            {
                if (!comprado)
                    return true;
            }
            return false;
        }

        public static void SairAgente(Agente agente)
        {
            for (int i = 0; i < Agentes.Count; i++)
            {
                if (Agentes.ElementAt(i) == agente)
                {
                    Agentes.RemoveAt(i);
                }
            }
        }

        public static void LimparMatriz()
        {
            for (int i = 0; i < Util.DIMENSAO_MATRIZ; i++)
            {
                for (int j = 0; j < Util.DIMENSAO_MATRIZ; j++)
                {
                    _matriz[i, j].Cor = Cor.BRANCO;
                }
            }
        }
    }
}
